
#ifndef __SSPROTO_NAME_TABLE_H
#define __SSPROTO_NAME_TABLE_H 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

namespace qb{
namespace proto{

class name_table {
public:
    typedef struct __st_node{
        const char * name ;
        size_t code ;       //哈希值
        size_t value ;      //节点值
    } node ;


    name_table() ;
    ~name_table() ;

    bool insert(const char * name , size_t value) ;
    bool remove(const char * name) ;
    bool find(const char * name , size_t& value) const ;
    bool update(const char * name , size_t value , size_t* old) ;

    void clear() ;

    inline size_t count() const {return count_ ;}
    inline size_t size() const {return size_ ;}

    inline node * nodes(int index) 
    {
        if(index < 0 || index >= (int)count_)
            return NULL ;

        return nodes_ + index ;
    }

    inline const node * nodes(int index) const 
    {
        if(index < 0 || index >= (int)count_)
            return NULL ;

        return nodes_ + index ;
    }    

    static size_t hash_value(const char * str , size_t size) ;
    size_t next_size() ;

    bool check_nodes() const;
    bool check_nodes(int (*cmp)(const node * s1 , const node *s2)) const;

    static int name_table_node_cmp(const name_table::node * s1 , const name_table::node *s2) ;

protected:
    /*
        测试用的函数，请勿使用

        nodes_中，首先按hash值排序，相等的hash，按name排序，
        相当于hash + name的升序排列。

        find_index是关键函数，他返回接近且小等于hash的节点下标。
        result = 0 ，表示code == hash 
        result = -1 ，表示code < hash 
        result = 1 ，表示code > hash
        result = -2 ，表示未知状态，同时返回值小于0
    */
    int find(const char * name , size_t hash , int& result) const ;
    bool insert(const char * name , size_t hash , size_t value) ;
    bool remove(const char * name , size_t hash) ;
    bool update(const char * name , size_t hash , size_t new_value , size_t *old_value) ;

    //非排序插入，需要指定max。如果超过max，还可以插入，但需要扩展
    bool unsort_insert(const char * name , size_t hash , size_t value , size_t max) ;
    //调用快速排序
    bool batch_sort() ;

    bool batch_insert(const node * ns , size_t count) ;
private:
    node * nodes_ ;
    size_t count_ ;          //nodes节点的有效值
    size_t size_ ;           //nodes节点的最大值

    bool extend(size_t count = 0) ; //扩大到count个节点
} ;

}
}

#endif  /** __SSPROTO_NAME_TABLE_H */
